/*
 * Class Pixel
 * ===========
 * Manages Pixels. It uses only one 32bit integer instead of 
 * 3 integers for colors + 1 integer for transparency
 */
package rayTracer;

import static rayTracer.ApplicationInterface.*;

public class Pixel implements Cloneable{
	private int pixelValue;	
	private static int[] shiftValues = {24, 16, 8, 0};
	
	//By default, a pixel is created to contain the color WHITE
	public Pixel(){
		pixelValue = 0x00;
	}
	
	public Pixel(int color){		
		pixelValue = color; 
	}
	
	public Pixel(int alpha, int red, int green, int blue){		
		setPixel(alpha, red, green, blue);
	}
	
	public Pixel(float rgb[]) {
		//setPixel(NO_TRANSPARENCY, (int)(rgb[0]*255), (int)(rgb[1]*255), (int)(rgb[2]*255));
		setPixel(255, Math.round(rgb[1]*255), Math.round(rgb[2]*255), Math.round(rgb[3]*255));
	}
	
	/*
	 * The pixel information is stored by shifting the values of the
	 * 4 components, so they dont overlap one another
	 */
	public void setPixel(int alpha, int red, int green, int blue){
		alpha &= 0xff;
		red &= 0xff;
		green &= 0xff;
		blue &= 0xff;
		pixelValue = (alpha << shiftValues[0]) | (red << shiftValues[1]) | (green << shiftValues[2] ) | blue;
	}
	
	public int getPixel(){
		return pixelValue;
	}
	
	/*
	 * Set the RGB component indicated by rgbPos, to the value given by second parameter 
	 * rgbPos parameter can be: ALPHA, RED, GREEN, BLUE as defined in LibInterface
	 * value parameter goes from 0 to 255
	 */	
	public void setRGBValue( RGB_POS rgbPos, int value){
		int pos = getPosition(rgbPos);		
		pixelValue = pixelValue | ( (value&0xff) << shiftValues[pos] );
	}
	
	/*
	 * Get the RGB component indicated by rgbPos, from the current Pixel
	 */
	public int getRGBValue(RGB_POS rgbPos){
		int pos = getPosition(rgbPos);
		return ( pixelValue >> shiftValues[pos] )  & 0xff;
	}
	
	public String toString(){
		StringBuffer str = new StringBuffer();		
		str.append(	"A = " + this.getRGBValue(RGB_POS.ALPHA) + ", " +
					"(R = " + this.getRGBValue(RGB_POS.RED) + "), " +
					"(G = " + this.getRGBValue(RGB_POS.GREEN) + "), " + 
					"(B = " + this.getRGBValue(RGB_POS.BLUE) + ")");
		return str.toString();
	}
	
	public Object clone(){
        Pixel obj=null;
        try{
            obj=(Pixel)super.clone();
        }catch(CloneNotSupportedException ex){
            System.out.println("No se puede duplicar");
        }        
        
        return obj;
    }
	
	/*
	 * Internal method to translate an RGB position to an integer, acoording
	 * to the definitions in LibInterface
	 */
	private int getPosition( RGB_POS rgbPos ){		
		switch( rgbPos ){
			case ALPHA : return 0;
			case RED : return 1;
			case GREEN : return 2;
			case BLUE : return 3;
			default : return 0;
		}	
	}	
}
